package org.manon.json.meta;

import java.lang.reflect.Method;
import java.lang.reflect.TypeVariable;

/**
 * @author <a href="mailto:jacques.militello@gmail.com">Jacques Militello</a>
 */
public final class MetaPropertyGeneric extends MetaProperty {

	private boolean _instance = false;
	private final Method _method;
	private MetaPropertyGeneric _parent;
	
	public MetaPropertyGeneric(String name, String label, Method method) {
		super(MetaPropertyType.GENERIC,name, label, method);
		_method = method;
		_parent = null;
	}
	
	public MetaPropertyGeneric(Class<?> returnType,MetaPropertyGeneric parent) {
		super(MetaPropertyType.GENERIC,parent.getName(), parent.getLabel(), returnType);
		_method = parent._method;
		_parent = parent;
		_instance = true;
	}

	public boolean isInstance() {
		return _instance;
	}
	
	public MetaPropertyGeneric getParent() {
		return _parent;
	}
	
	@SuppressWarnings("rawtypes")
	public String getGenericType() {
		return ((TypeVariable)_method.getGenericReturnType()).getName();
	}
	
	public MetaPropertyGeneric clone(Class<?> type) {
		return new MetaPropertyGeneric(type,this);
	}
	
	/**
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(MetaProperty otherProperty) {
		
		if (otherProperty instanceof MetaPropertyGeneric) {
			return getLabel().compareTo(otherProperty.getLabel());
		}
		
		if (otherProperty instanceof MetaPropertyDiscriminator ||
				otherProperty instanceof MetaPropertySingleValue) {
			return 1;
		}
		
		return -1;
	}

	@Override
	public String toString() {
		final StringBuilder builder = new StringBuilder(128);
		builder.append("Property Generic : ");
		toString(builder);
		builder.append(", instance=[").append(_instance).append("]");
		builder.append(", method=[").append(_method).append("]");
		builder.append(", parent=[").append(_parent).append("]");
		return builder.toString();
	}
	
	/**
	 * @see org.manon.json.meta.MetaProperty#accept(org.manon.json.meta.MetaPropertyVisitor)
	 */
	@Override
	public void accept(MetaPropertyVisitor visitor) {
		visitor.visit(this);
	}
}